package com.xxxx.core.shiro;

import com.xxxx.core.session.ShiroSessionManager;
import com.xxxx.core.token.ITokenProcessor;
import com.xxxx.core.token.TokenParameter;
import com.xxxx.entity.Permission;
import com.xxxx.entity.Role;
import com.xxxx.entity.User;
import com.xxxx.service.IPermissionService;
import com.xxxx.service.IRolePermissionService;
import com.xxxx.service.IUserRoleService;
import com.xxxx.service.IUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * Created by wangyan on 2017/8/6.
 */
public class MyShiroRealm extends AuthorizingRealm {

    private static final Logger logger = LoggerFactory.getLogger(MyShiroRealm.class);

    @Autowired
    private ShiroSessionManager shiroSessionManager;
    @Autowired
    private IUserService userService;
    @Autowired
    IUserRoleService userRoleService;
    @Autowired
    IPermissionService permissionService;
    @Autowired
    IRolePermissionService rolePermissionService;

    @Override
    public boolean supports(AuthenticationToken token) {
        //仅支持StatelessToken类型的Token
        return token instanceof StatelessToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        System.out.println("-----------ziyuzile.cn-----------principals值=" + principals.getPrimaryPrincipal() + "," + "当前类=MyShiroRealm.doGetAuthorizationInfo()");
        User userInfo  = userService.selectByLoginName(String.valueOf(principals.getPrimaryPrincipal()));
        List<Role> roleList = userRoleService.selectRolesByUserId(userInfo.getId());

        for(Role role:roleList){
            authorizationInfo.addRole(role.getRole());
            for(Permission p:rolePermissionService.selectPermissionsByRoleId(role.getId())){
                authorizationInfo.addStringPermission(p.getPermission());
            }
        }
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken atoken) throws AuthenticationException {
        System.out.println("MyShiroRealm.doGetAuthenticationInfo()");
        StatelessToken token = (StatelessToken) atoken;
        TokenParameter tp = token.getTp();
        String userName = (String) token.getPrincipal();
        ITokenProcessor tokenProcessor = token.getTokenProcessor();
        String tokenStr = tokenProcessor.generateToken(tp);
        if (tokenStr == null || !shiroSessionManager.validateOnlineSession(userName, tokenStr)) {
            logger.error("User [{}] authenticate fail in System, maybe session timeout!", userName);
            throw new AuthenticationException("User " + userName + " authenticate fail in System");
        }

        return new SimpleAuthenticationInfo(userName, tokenStr, getName());
    }
}
